# -*- coding: utf-8 -*-
"""
文件操作工作线程模块

提供异步文件操作功能，避免UI阻塞
"""

from pathlib import Path
from PySide2.QtCore import QThread, Signal
from gglobal import logger


class FileOperationWorker(QThread):
    """文件操作工作线程"""
    
    # 信号定义
    operation_finished = Signal(str, bool, list, list)  # 操作完成信号 (操作类型, 是否成功, 成功文件列表, 失败文件列表)
    progress_updated = Signal(str, int)  # 进度更新信号
    
    def __init__(self, operation_type, client_thread, *args, **kwargs):
        super().__init__()
        self.operation_type = operation_type
        self.client_thread = client_thread
        self.args = args
        self.kwargs = kwargs
        self.success_files = []
        self.failed_files = []
        self._is_cancelled = False  # 取消标志
        
    def cancel_operation(self):
        """取消当前操作"""
        self._is_cancelled = True
        logger.info(f"正在取消操作: {self.operation_type}")
        
        # 如果有客户端线程连接，发送Ctrl+C中断命令
        if self.client_thread and hasattr(self.client_thread, 'send_ctrl_c'):
            try:
                self.client_thread.send_ctrl_c()
                logger.info("已发送Ctrl+C中断信号")
            except Exception as e:
                logger.warning(f"发送Ctrl+C信号失败: {e}")
        
    def run(self):
        """执行文件操作"""
        try:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info(f"操作已取消: {self.operation_type}")
                self.operation_finished.emit(self.operation_type, False, [], ["操作已取消"])
                return
                
            if self.operation_type == "download":
                self._download_files()
            elif self.operation_type == "upload":
                self._upload_files()
            elif self.operation_type == "delete":
                self._delete_files()
            elif self.operation_type == "compress":
                self._compress_files()
            elif self.operation_type == "extract":
                self._extract_files()
            elif self.operation_type == "change_directory":
                self._change_directory()
            elif self.operation_type == "list_directory":
                self._list_directory()
        except Exception as e:
            logger.error(f"文件操作异常 {self.operation_type}: {e}")
            self.operation_finished.emit(self.operation_type, False, [], [str(e)])
    
    def _download_files(self):
        """下载文件"""
        files, download_dir, current_path = self.args
        success_count = 0
        
        for file_info in files:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info("下载操作已取消")
                self.operation_finished.emit("download", False, self.success_files, self.failed_files + ["操作已取消"])
                return
                
            # 使用正斜杠拼接远程路径，避免Windows路径分隔符问题
            if current_path.endswith('/'):
                remote_path = f"{current_path}{file_info.name}"
            else:
                remote_path = f"{current_path}/{file_info.name}"
            local_path = str(Path(download_dir) / file_info.name)
            
            logger.info(f"下载文件: {remote_path} -> {local_path}")
            
            try:
                success = self.client_thread.download_file(remote_path, local_path)
                if success:
                    success_count += 1
                    self.success_files.append(file_info.name)
                    self.progress_updated.emit(f"下载: {file_info.name}", int((success_count / len(files)) * 100))
                else:
                    self.failed_files.append(file_info.name)
                    logger.error(f"下载文件失败 {file_info.name}: 操作返回失败")
            except Exception as e:
                self.failed_files.append(file_info.name)
                logger.error(f"下载文件失败 {file_info.name}: {e}")
        
        success = success_count == len(files)
        self.operation_finished.emit("download", success, self.success_files, self.failed_files)
    
    def _upload_files(self):
        """上传文件"""
        local_files = self.args[0]
        success_count = 0
        
        for local_file in local_files:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info("上传操作已取消")
                self.operation_finished.emit("upload", False, self.success_files, self.failed_files + ["操作已取消"])
                return
                
            local_path = str(local_file)
            remote_file_name = Path(local_file).name
            
            logger.info(f"上传文件: {local_path} -> {remote_file_name}")
            
            try:
                # 使用新方法：返回结构化结果字典
                result = self.client_thread.upload_file_detail(local_path, remote_file_name)
                success = bool(result.get('success', False))
                if success:
                    success_count += 1
                    self.success_files.append(remote_file_name)
                    self.progress_updated.emit(f"上传: {remote_file_name}", int((success_count / len(local_files)) * 100))
                else:
                    self.failed_files.append(remote_file_name)
                    # 输出更详细的错误信息
                    logger.error(f"上传文件失败 {remote_file_name}: {result.get('message', '操作返回失败')}")
            except Exception as e:
                self.failed_files.append(remote_file_name)
                logger.error(f"上传文件失败 {remote_file_name}: {e}")
        
        success = success_count == len(local_files)
        self.operation_finished.emit("upload", success, self.success_files, self.failed_files)
    
    def _delete_files(self):
        """删除文件"""
        files = self.args[0]
        success_count = 0
        
        for file_info in files:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info("删除操作已取消")
                self.operation_finished.emit("delete", False, self.success_files, self.failed_files + ["操作已取消"])
                return
                
            file_name = file_info.name
            logger.info(f"删除文件: {file_name}")
            
            try:
                success = self.client_thread.remove_file(file_name)
                if success:
                    success_count += 1
                    self.success_files.append(file_name)
                else:
                    self.failed_files.append(file_name)
            except Exception as e:
                logger.error(f"删除文件失败 {file_name}: {e}")
                self.failed_files.append(file_name)
        
        success = success_count == len(files)
        self.operation_finished.emit("delete", success, self.success_files, self.failed_files)
    
    def _compress_files(self):
        """压缩文件"""
        files, format_choice = self.args
        success_count = 0
        
        for file_info in files:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info("压缩操作已取消")
                self.operation_finished.emit("compress", False, self.success_files, self.failed_files + ["操作已取消"])
                return
                
            file_name = file_info.name
            logger.info(f"压缩文件: {file_name} 格式: {format_choice}")
            
            try:
                success = self.client_thread.compress_file(file_name, format_choice)
                if success:
                    success_count += 1
                    self.success_files.append(file_name)
                else:
                    self.failed_files.append(file_name)
                    logger.error(f"压缩文件失败 {file_name}: 操作返回失败")
            except Exception as e:
                self.failed_files.append(file_name)
                logger.error(f"压缩文件失败 {file_name}: {e}")
        
        success = success_count == len(files)
        self.operation_finished.emit("compress", success, self.success_files, self.failed_files)
    
    def _extract_files(self):
        """解压文件"""
        archive_files = self.args[0]
        success_count = 0
        
        for file_info in archive_files:
            # 检查是否已被取消
            if self._is_cancelled:
                logger.info("解压操作已取消")
                self.operation_finished.emit("extract", False, self.success_files, self.failed_files + ["操作已取消"])
                return
                
            file_name = file_info.name
            logger.info(f"解压文件: {file_name}")
            
            try:
                success = self.client_thread.decompress_file(file_name)
                if success:
                    success_count += 1
                    self.success_files.append(file_name)
                else:
                    self.failed_files.append(file_name)
                    logger.error(f"解压文件失败 {file_name}: 操作返回失败")
            except Exception as e:
                self.failed_files.append(file_name)
                logger.error(f"解压文件失败 {file_name}: {e}")
        
        success = success_count == len(archive_files)
        self.operation_finished.emit("extract", success, self.success_files, self.failed_files)
    
    def _change_directory(self):
        """切换目录"""
        path = self.args[0]
        try:
            success = self.client_thread.change_directory(path)
            if success:
                # cd成功后更新文件列表
                self.client_thread.list_directory()
            self.operation_finished.emit("change_directory", success, [], [])
        except Exception as e:
            logger.error(f"切换目录失败: {e}")
            self.operation_finished.emit("change_directory", False, [], [str(e)])
    
    def _list_directory(self):
        """列出目录"""
        try:
            files = self.client_thread.list_directory()
            success = files is not None and len(files) >= 0
            self.operation_finished.emit("list_directory", success, [], [])
        except Exception as e:
            logger.error(f"列出目录失败: {e}")
            self.operation_finished.emit("list_directory", False, [], [str(e)])